﻿using System;
using System.Collections.Generic;
using Fujitsu.JiraAnalysis.DAL;
using System.Threading;

namespace Fujitsu.JiraAnalysis.ReplicationService
{
    interface ICommand
    {
        void Execute();
    }

    class SyncCommand : ICommand
    {
        public Project Project { get; set; }
        Synchronize.ProjectSync projectSync = new Synchronize.ProjectSync();

        public SyncCommand(Project project)
        {
            Project = project;
        }

        public void Execute()
        {
            if (Project == null)
                return;
            var adapterCreator = new TrackingSystemAdapter.AdapterCreator();
            projectSync.ReplicateProject(Project, adapterCreator);
        }
    }

    class CommandDispatcher
    {
        private List<ICommand> commands = new List<ICommand>();
        private int NumberOfRunningThreads { get; set; }
        private int MaxNumberOfRunningThreads { get; set; }

        public CommandDispatcher()
        {
            NumberOfRunningThreads = 0;
            try
            {
                var maxNumberOfRunningThreads =
                    System.Configuration.ConfigurationManager.AppSettings["NumberOfSimultaneouslyReplicatedProjects"];
                if (string.IsNullOrEmpty(maxNumberOfRunningThreads))
                    throw new InvalidOperationException();
                MaxNumberOfRunningThreads = int.Parse(maxNumberOfRunningThreads);
            }
            catch (InvalidOperationException)
            {
                MaxNumberOfRunningThreads = int.MaxValue;
            }
        }

        public void ExecuteCommand(ICommand command)
        {
            while (NumberOfRunningThreads >= MaxNumberOfRunningThreads)
            { }
            var thread = new Thread(LaunchProjectSync);
            commands.Add(command);
            thread.Name = string.Format("CommandThread_{0}", commands.Count);
            thread.Start(command);
            NumberOfRunningThreads++;
        }

        private void LaunchProjectSync(object _command)
        {
            var command = _command as ICommand;
            command.Execute();
            NumberOfRunningThreads--;
        }
    }
}
